<?php

namespace api\modules\manage\resources;

use api\modules\manage\models\DictElements;
use api\modules\manage\models\DictTypeDefine;
use api\utils\StringUtil;
use yii\base\BaseObject;
use Yii;
use yii\db\ActiveQuery;

class ElementResource extends BaseObject
{
    /** type枚举值常量定义 */
    const TYPE_PERIOD = 1;
    const TYPE_STATUS = 2;
    const TYPE_FIXED = 3;
    const TYPE_FLOW = 4;
    const TYPE_CARD = 5;
    const TYPE_INFO = 6;
    const TYPE_PRINT = 7;
    const TYPE_MENU = 8;
    const TYPE_TAB = 9;
    const TYPE_FILTER = 10;
    const TYPE_SORT = 11;
    const TYPE_TAG_ACTION = 12;
    const TYPE_TAG = 13;
    const TYPE_NOTIFICATION = 14;
    const TYPE_KEYWORDS = 15;

    /** state枚举值定义 */
    const STATE_DELETED = 0;
    const STATE_ENABLED = 1;
    const STATE_DISABLED = 2;

    public $params;
    protected $attributes;
    public $id;
    public $formatType;

    const ALLOW_TYPES = [self::TYPE_PERIOD,self::TYPE_STATUS,self::TYPE_FIXED,self::TYPE_FLOW,self::TYPE_TAG,
        self::TYPE_TAG_ACTION,self::TYPE_CARD,self::TYPE_INFO,self::TYPE_PRINT,self::TYPE_FILTER,self::TYPE_SORT,
        self::TYPE_NOTIFICATION,self::TYPE_KEYWORDS];

    public function init()
    {
        parent::init();
        $this->initType();
    }

    protected function initType()
    {
        if($this->formatType){
            $this->params['type'] = $this->formatType;
        }
    }

    private function validate()
    {
        if(isset($this->params['type'])){
            if(!(in_array($this->params['type'],self::ALLOW_TYPES) || $this->formatType)){
                throw new \Exception(Yii::t('app', 'params type error'));
            }
        }else{
            throw new \Exception(Yii::t('app', 'need params type'));
        }
    }

    public function createElement()
    {
        $this->validate();
        $this->initAttributes();
        $element = new DictElements($this->attributes[__CLASS__]);
        $element->save();
        $this->id = $element->id;
        return true;
    }

    public function viewElement()
    {
        $element = $this->findElement();
        return $element->toArray();
    }

    public function updateElement()
    {
        $element = $this->findElement();
        $this->initAttributes(false);
        $element->setAttributes($this->attributes[__CLASS__]);
        $element->save();
        return true;
    }

    public function deleteElement()
    {
        $element = $this->findElement();
        $element->setAttribute('state',self::STATE_DELETED);
        $element->save();
        return true;
    }

    public function switchElement()
    {
        $element = $this->findElement();
        switch ($element->state){
            case self::STATE_ENABLED:
                $target = self::STATE_DISABLED;
                break;
            case self::STATE_DISABLED:
                $target = self::STATE_ENABLED;
                break;
            default:
                $target = self::STATE_DELETED;
                break;
        }
        $element->setAttribute('state',$target);
        $element->save();
    }

    protected function initAttributes($isNew = true)
    {
        $type = $this->params['type'];
        $this->attributes[__CLASS__] = [
            'name' => $this->params['name'],
            'description' => $this->params['description'],
            'ext' => $this->params['ext'],
            'state' => 1,
        ];
        if($isNew){
            $this->attributes[__CLASS__] = array_merge($this->attributes[__CLASS__],[
                'code' => self::generateCode($type),
                'type' => $type,
            ]);
        }
    }

    /**
     * @param int $type 字典类型
     * @return string 生成的唯一code
     */
    private static function generateCode(int $type)
    {
        $codeMain = Yii::$app->params['codeMain'];
        $define = DictTypeDefine::findOne(['id' => $type]);
        $newMax = $define['max'] + 1;
        $code = $codeMain . '-' . $define['code'] . '-' . sprintf('%03s', $newMax);
        $define->setAttribute('max', $newMax);
        $define->save();
        return $code;
    }

    private function findElement()
    {
        if($this->formatType){
            $eqType = $this->formatType;
        }else{
            $eqType = self::ALLOW_TYPES;
        }
        $element = DictElements::findOne(['id' => $this->id, $eqType]);
        if($element){
            return $element;
        }else{
            throw new \Exception(\Yii::t('app','not found'));
        }
    }

    public static function getCondition($params)
    {
        $condition = [];
        if (isset($params['state'])) {
            $condition['state'] = $params['state'];
        }
        if (isset($params['code'])) {
            $condition['code'] = $params['code'];
        }
        if (isset($params['type'])) {
            $condition['type'] = $params['type'];
        }
        return $condition;
    }

    public static function setQueryCondition(ActiveQuery $query,$params,$conditions)
    {
        $mixConditions = ['and',
            ['and',
                $conditions
            ],
        ];
        if (isset($params['mixed'])){
            $mixConditions[] = [
                'or',
                ['name' => $params['mixed']],
                ['code' => $params['mixed']]
            ];
        }
        $query->andFilterWhere($mixConditions);
        return $query;
    }
}